Software solutions marketed for data security allow an owner of sensitive information to specify access and usage rights for the electronic documents, electronic messages, or more generically any data objects that contain sensitive information. As used here a control policy is a bundle of access and usage rights defined in the context of a rights-management system, and a protected data object is a data object with a specific control policy, not just a blanket “all rights”. Unfortunately, control policies and their supporting rights-management systems do not comprise a complete and comprehensive solution for the data security market. Even shipping a single rights-aware application will generally fall short of a complete and comprehensive solution because of the lack of interoperability with other applications. A complete and comprehensive solution, such as the one sold by Liquid Machines, Inc. (assignee), offers a suite of software applications that are each integrated with one or more rights-management systems. These rights-aware applications can manipulate both protected and unprotected data objects, and when manipulating protected data objects, rights-aware applications seamlessly enforce the protections (i.e., the access and usage rights) afforded by the specified control policies.
Central to the correct functioning of rights-aware applications is the ability to maintain the association of a control policy with a data object and its protected content, independent of the type of persistent or transient storage (e.g., temporary files or clipboard buffers) used by the application during manipulation of the data object. Given that many existing applications can manipulate two or more data objects at the same time, a comprehensive solution must be able to maintain the aforementioned associations even when an application concurrently manipulates multiple data objects with different control policies.
When specifying a control policy, most rights-management systems allow the owners of data objects to specify access and usage rights in terms of simple actions taken by principals on the data objects. For example, Alice may give Bob the ability to open and print the finance report, but not make changes to it. Here, Alice “owns” the finance report and sets the control policy associated with it. Bob is a principal in the rights-management system whose interactions with the finance report through applications are restricted to be within the bounds of the report's control policy.
So, how are the rights described in a control policy checked within an application to restrict a principal's activities with each protected data object? The answer to this question is best understood by viewing the integration of a rights-management system with an application as a two-step process. This two-step process connects the complex semantics of a control policy right with one or more sequences of specific low-level program events whose composition indicates a user's attempt to exercise that right. This two-step process occurs even in the case where the rights-management system provides a software developer kit (SDK) to aid in the creation of a rights-aware application.
Working from control policies down to program events, integrating an application with a rights-management system begins with a translation of the high-level semantics of control policies into the collections of simple program events. One can think about these as generic program events (e.g., an event which opens a file). In the second step in the process, the generic program events are mapped to low-level program operations (or events), e.g., a call to “CreateFile” in the WINDOWS operating system.
Though several applications may compose the same set or sets of generic program events to indicate a particular control policy right, a comprehensive solution to the data security problem must, in the worst case, support for each application a unique mapping from control policy rights to compositions of generic program events. Given multiple different rights-management systems, each application may also require, in the worst case, unique mappings from the specific control policy rights of each rights-management system to compositions of that application's generic program events.
As a very simple example, checking and appropriately reacting to an attempt by Bob to save changes to the protected finance report could appear within an application as the creation of a file handle based on the new file name followed later by a write request on that file handle with a program buffer containing data from the protected finance report. Creating a user-friendly error message and single audit log entry explaining that Bob attempted and did not have the right to perform this action would require collecting and correlating information from at least three separate program events. In general, creating a minimum number of appropriate error messages and log entries requires a careful understanding of the program context to differentiate between similar sequences of separate program events.
To complete the integration of a rights-management system with an application, one must determine for each application which actual program operations (or low-level program events) map to the generic program events used in the first step, know how to post operations as generic events to the rights-management system, and understand how to enforce the edicts of the rights-management system. In general, it is straightforward to map actual program operations to semantically equivalent generic program events, so the only semantically difficult mapping step is the previous one.
Clearly, the two steps in this process require different types of expertise. For ease of exposition, let's call the first person a product manager and the second a software engineer. The product manager is responsible for composing generic program events and working with control policies. The product manager must understand the operation of the target application in terms of generic program events and the semantics of the rights in the rights-management system. The software engineer, on the other hand, is responsible for mapping actual program operations to generic program events and for inserting code similar to that used for inline reference monitors into the application. The software engineer must understand the low-level details of the application's implementation (e.g., it uses “CreateFile” to open files) and the building of inline reference monitors.
An outcome of this separation is that the software engineer needs to know practically nothing about the complex operation of an application and the model of data security proposed for this application. The software engineer can quickly and confidently integrate inline reference monitors into the application, leaving out the details of mapping collections of events to policy rights. It is this mapping that is often controversial, difficult to get right the first time, and apt to change as threats evolve and new ones surface.
Without this two-step structuring, a product manager needs to involve a software engineer when the product manager desires to change the composition or mapping of program events to rights. Furthermore, without such a structuring, changes that only affect the manner in which an application should enforce the control policies of the rights-management system almost always imply low-level changes in the code of the application. Such low-level changes may result in complex software bugs that cause the application to crash. Of course, it is always possible that a change in the composition or mapping of program events to rights may be done incorrectly, but by eliminating the tedium of having to deal with actual program operations (and instead deal with generic program events), it is more likely that a mistake in the data security model results simply in an undesired data leak rather than a program crash. The former allows the user to continue working with a loss of data protection; the latter inhibits the user's ability to work and subjects users to a potentially catastrophic loss of data.
When reviewing existing approaches, one is interested in the structuring of the connection between an application and a rights-management system, and in the technology used for mapping events in the application to policy rights in the rights-management system. Without loss of generality, it is assumed that all rights-management systems provide a set of application programming interfaces (APIs) to support integration of the rights-management system into an application.
A straightforward approach for integrating an application and a rights-management system is to add code to the application which directly invokes methods in the rights-management system's API. Such an approach produces a large amount of code unique to the application, the particular rights-management system used, and the specific rights to be enforced. This large engineering cost is acceptable as long as it is non-recurring and can be amortized over the lifetime of the resulting rights-aware application. However, in many markets it is important to integrate many applications with several different rights-management systems. For example, inserting into code a check which checks individual rights when the code is about to perform a document save is manageable when such a check (or several checks from several applications) is inserted into a single rights-management system. In contrast, having to insert the check (or several checks from several applications) into multiple rights-management systems is not as manageable. Maintenance also becomes a management nightmare. Accordingly, there needs to be solutions which minimize the engineering cost of integration.
One well-known way to reduce the cost of integration is to structure the integration so that it tracks important application events and maps them to actions of significance that are controlled by the rights-management system using a well-defined computational model. Models commonly appearing in rights-managed applications are state machines or automata.
When program events are filtered and processed locally (at the point in the code where the event resides), the integration yields a design based on a distributed state machine. Though distributed state machines have their advantages, they result in a rights-aware application where the rules and state controlling the program's execution are distributed and tightly interleaved with the application's code. The result is an integration that is hard to debug if mistakes are identified in the mapping of program events to policy rights, or hard to update robustly if modifications are necessary in this mapping because of a change to the rights-management system (e.g., the addition of new rights). Furthermore, such integration makes it difficult to port to a new rights-management system.
Erlingsson and Schneider have suggested that security automata are an appropriate formalism for integrating into an application a reference monitor enforcing any security policy, of which a rights-management system is an instance. Ulfar Erlingsson and Fred B. Schneider. “SASI Enforcement of Security Policies: A Retrospective,” Proceedings of the 1999 Workshop on New Security Paradigms, pp. 87-95, 1999 (hereinafter “Erlingsson & Schneider”). Program events correspond to the input alphabet of the automaton; the automaton states encode the state of the application with respect to its security policy; and the transitions between the states encode the actual security policies. Though this centralized approach eliminates the robustness and testability issues cited with a distributed design, Erlingsson and Schneider admit that the two prototypes that they built based on this idea were not practical tools. In particular, the authors admit that it is too limiting to have to create automaton states for all possible states of the monitored program. They express the desire for a system where it is easy to check application-level abstractions (e.g., the values of string variables). As stated earlier, the policies of modern rights-management systems are often specified using application-level abstractions.
Yet, security automaton demonstrate two characteristics that are important for our target market. Through the use of a Security Automaton Language (SAL), Erlingsson and Schneider were able to hide low-level programming details (e.g., the placement of data and relative offsets of code labels) from those responsible for encoding security policies in SAL. This led to more robust systems with fewer correctness problems. Furthermore, Schneider points out that the use of an automaton simplifies prototyping and testing of security policies. Fred B. Schneider. “Enforceable Security Policies,” ACM Transactions on Information and System Security, 3(1):30-50, February 2000 (hereinafter “Schneider”). Testing is in fact “just a matter of running the automaton.” Schneider.
In summary, there is a recognition in the industry that one should centralize the component that tracks program events and maps those events to policy rights, that one should allow those responsible for mapping program events to policy rights to be able to specify this mapping without having to deal with low-level implementation details of the application and rights-management system, and that one should base this component on a computational model that allows for quick prototyping and easy testing of new control policy specifications. On the other hand, the industry does not appear to have identified a computational model with the aforementioned benefits that also can check runtime values based on application-level abstractions. Finally, the industry does not seem to have a strong notion of how to repeatedly develop rights-aware applications such that the user messages and audit log entries produced are semantically rich and accurately reflect the current application and user activity.